﻿#include "BlockRegistry.h"

#include "World/BlockModel.h"
#include "Asset/AssetManager.h"

BlockRegistry::BlockRegistry()
{
}

void BlockRegistry::RegisterBlock(const Block &block)
{
  int id = 0;

  // 如果方块名已经被注册，则替换原来的方块
  if (m_blockNames.contains(block.name))
  {
    LOG_WARN("Block: {} already registered and will be replaced!", block.name);
    assert(m_blockNameToID.contains(block.name));
    id = m_blockNameToID[block.name];
  }
  else
  {
    // 查找一个空闲的ID
    if (m_blockNameToID.contains(block.name))
    {
      // 这种情况是存档中读取了m_blockNameToID，但是m_blocks中没有对应的方块
      id = m_blockNameToID[block.name];
    }
    else
    {
      for (int i = 1; i < m_blocks.size(); i++)
      {
        if (!m_blocks[i])
        {
          id = i;
          break;
        }
      }
    }
    if (id == 0)
    {
      id = m_blocks.size();
    }

    LOG_INFO("Registered block: {} with ID: {}", block.name, id);
    if (id >= m_blocks.size())
    {
      m_blocks.resize(std::max(id + 1, (int)m_blocks.size() * 2));
    }
  }

  m_blocks[id] = (std::move(block));
  m_blocks[id].model = AssetManager::LoadAsset<BlockModel>("assets/models/block/" + block.name + ".json");
  m_blockNameToID[block.name] = id;
  m_blockNames.insert(block.name);


}

Block *BlockRegistry::GetBlock(Block::ID id)
{
  if (id < m_blocks.size())
    return &m_blocks[id];
  if (id == 0)
  {
    return nullptr;
  }
  return &m_blocks[0];
}

Block::ID BlockRegistry::GetBlockID(const std::string &name)
{
  auto it = m_blockNameToID.find(name);
  if (it != m_blockNameToID.end())
    return it->second;
  return 0;
}

void BlockRegistry::RegisterDefaultBlocks()
{
  RegisterBlock({"air", Block::RenderType::Air});
  RegisterBlock({"stone", Block::RenderType::Opaque, Block::BlockModelType::Full, glm::vec4(0.498, 0.498, 0.498, 1)});
  RegisterBlock({"dirt", Block::RenderType::Opaque, Block::BlockModelType::Full, glm::vec4(0.588, 0.424, 0.29, 1)});
  RegisterBlock({"sand", Block::RenderType::Opaque, Block::BlockModelType::Full, glm::vec4(0.82, 0.792, 0.576, 1)});
  RegisterBlock({"bedrock", Block::RenderType::Opaque, Block::BlockModelType::Full, glm::vec4(0.341, 0.341, 0.341, 1)});
  RegisterBlock({"grass_block", Block::RenderType::Opaque, Block::BlockModelType::Full, glm::vec4(0.376, 0.627, 0.212, 1)});
}
